package es.mllacer.qqsm;

import java.util.List;

import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import es.mllacer.qqsm.dialogs.BackPressDialog;
import es.mllacer.qqsm.dialogs.LooserDialog;
import es.mllacer.qqsm.dialogs.NextQuestionDialog;
import es.mllacer.qqsm.dialogs.WinnerDialog;
import es.mllacer.qqsm.runnables.LocalScoreRunnable;
import es.mllacer.qqsm.runnables.RemoteScoreRunnable;
import es.mllacer.qqsm.util.Question;
import es.mllacer.qqsm.util.QuestionList;
import es.mllacer.qqsm.util.Utils;

public class Play extends FragmentActivity {

	private Drawable phoneDrawable = null;
	private Drawable audienceDrawable = null;

	private List<Question> questions = null;
	private String[] quantities = null;

	private TextView questionNumberView = null;
	private TextView playQuantityView = null;

	private TextView questionView = null;
	private Button answer1Button = null;
	private Button answer2Button = null;
	private Button answer3Button = null;
	private Button answer4Button = null;

	private int counter = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.play_layout);

		phoneDrawable = getResources().getDrawable(R.drawable.phone);
		audienceDrawable = getResources().getDrawable(R.drawable.audience);

		questions = QuestionList.getQuestionsList(getResources().getXml(
				R.xml.questions));

		quantities = new String[] { "0", "100", "200", "300", "500", "1000",
				"2000", "4000", "8000", "16000", "32000", "64000", "125000",
				"250000", "500000", "1000000" };

		questionNumberView = (TextView) findViewById(R.id.question_number);
		playQuantityView = (TextView) findViewById(R.id.play_quantity);

		questionView = (TextView) findViewById(R.id.question);
		answer1Button = (Button) findViewById(R.id.button1);
		answer2Button = (Button) findViewById(R.id.button2);
		answer3Button = (Button) findViewById(R.id.button3);
		answer4Button = (Button) findViewById(R.id.button4);

		// Update the property counter
		updateCounter(getPlayPreferences().getInt(Utils.QUESTION_PREFERENCE, 0));
		// Load question depending on the counter
		loadQuestion();
		// Load last state depending on menu items selected...
		loadState();
	}

	@Override
	protected void onPause() {
		// store counter (question number) preferences
		storeQuestionPreferences();
		super.onPause();
	}

	@Override
	public void onBackPressed() {
		BackPressDialog.getInstance().show(getSupportFragmentManager(), "Back");
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.play, menu);
		// Load last menu options selected from the preferences
		loadMenuState(menu);

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		SharedPreferences prefs = getPlayPreferences();
		SharedPreferences.Editor editor = prefs.edit();
		Question question = getQuestion();
		int option = item.getItemId();

		switch (option) {
		case R.id.menu_play_fifty:
			updateButtonFromFifty(Integer.parseInt(question.getFifty1()));
			updateButtonFromFifty(Integer.parseInt(question.getFifty2()));
			editor.putBoolean(Utils.FIFTY_USED_PREFERENCE, true);
			editor.putBoolean(Utils.FIFTY_SELECTED_PREFERENCE, true);
			break;
		case R.id.menu_play_phone:
			updateButtonFromPhone(Integer.parseInt(question.getPhone()),
					prefs.getBoolean(Utils.AUDIENCE_SELECTED_PREFERENCE, false));
			editor.putBoolean(Utils.PHONE_USED_PREFERENCE, true);
			editor.putBoolean(Utils.PHONE_SELECTED_PREFERENCE, true);
			break;
		case R.id.menu_play_audience:
			updateButtonFromAudience(Integer.parseInt(question.getAudience()),
					prefs.getBoolean(Utils.PHONE_SELECTED_PREFERENCE, false));
			editor.putBoolean(Utils.AUDIENCE_USED_PREFERENCE, true);
			editor.putBoolean(Utils.AUDIENCE_SELECTED_PREFERENCE, true);
			break;
		}

		// Disable the item selected
		item.setEnabled(false);
		// Save the option as used as selected
		editor.commit();

		return super.onOptionsItemSelected(item);
	}

	private void updateButtonFromFifty(int option) {
		switch (option) {
		case 1:
			answer1Button.setEnabled(false);
			break;
		case 2:
			answer2Button.setEnabled(false);
			break;
		case 3:
			answer3Button.setEnabled(false);
			break;
		case 4:
			answer4Button.setEnabled(false);
			break;
		}
	}

	private void updateButtonFromPhone(int option, boolean audienceUsed) {
		Drawable left = phoneDrawable;
		Drawable right = audienceUsed ? audienceDrawable : null;
		switch (option) {
		case 1:
			answer1Button.setCompoundDrawablesWithIntrinsicBounds(left, null,
					hasDrawableApplied(answer1Button, right) ? right : null,
					null);
			break;
		case 2:
			answer2Button.setCompoundDrawablesWithIntrinsicBounds(left, null,
					hasDrawableApplied(answer2Button, right) ? right : null,
					null);
			break;
		case 3:
			answer3Button.setCompoundDrawablesWithIntrinsicBounds(left, null,
					hasDrawableApplied(answer3Button, right) ? right : null,
					null);
			break;
		case 4:
			answer4Button.setCompoundDrawablesWithIntrinsicBounds(left, null,
					hasDrawableApplied(answer4Button, right) ? right : null,
					null);
			break;
		}
	}

	private void updateButtonFromAudience(int option, boolean phoneUsed) {
		Drawable right = audienceDrawable;
		Drawable left = phoneUsed ? phoneDrawable : null;
		switch (option) {
		case 1:
			answer1Button.setCompoundDrawablesWithIntrinsicBounds(
					hasDrawableApplied(answer1Button, left) ? left : null,
					null, right, null);
			break;
		case 2:
			answer2Button.setCompoundDrawablesWithIntrinsicBounds(
					hasDrawableApplied(answer2Button, left) ? left : null,
					null, right, null);
			break;
		case 3:
			answer3Button.setCompoundDrawablesWithIntrinsicBounds(
					hasDrawableApplied(answer3Button, left) ? left : null,
					null, right, null);
			break;
		case 4:
			answer4Button.setCompoundDrawablesWithIntrinsicBounds(
					hasDrawableApplied(answer4Button, left) ? left : null,
					null, right, null);
			break;
		}
	}

	private boolean hasDrawableApplied(Button b, Drawable d) {
		if (d != null) {
			for (Drawable applied : b.getCompoundDrawables()) {
				if (d.equals(applied)) {
					return true;
				}
			}
		}
		return false;
	}

	private void loadMenuState(Menu menu) {
		SharedPreferences prefs = getPlayPreferences();

		MenuItem fifty = menu.findItem(R.id.menu_play_fifty);
		MenuItem phone = menu.findItem(R.id.menu_play_phone);
		MenuItem audience = menu.findItem(R.id.menu_play_audience);

		if (prefs.getBoolean(Utils.FIFTY_USED_PREFERENCE, false)) {
			fifty.setEnabled(false);
		}
		if (prefs.getBoolean(Utils.PHONE_USED_PREFERENCE, false)) {
			phone.setEnabled(false);
		}
		if (prefs.getBoolean(Utils.AUDIENCE_USED_PREFERENCE, false)) {
			audience.setEnabled(false);
		}
	}

	public void updateCounter(int qNumber) {
		counter = qNumber;
	}

	public int getCounter() {
		return counter;
	}

	public void loadQuestion() {
		Question q = getQuestion();
		if (q == null) {
			return;
		}
		questionNumberView.setText(q.getNumber());
		int qNumber = Integer.parseInt(q.getNumber());
		playQuantityView
				.setText(qNumber < quantities.length ? quantities[qNumber] : "");
		questionView.setText(q.getText());

		answer1Button.setText(q.getAnswer1());
		answer2Button.setText(q.getAnswer2());
		answer3Button.setText(q.getAnswer3());
		answer4Button.setText(q.getAnswer4());

		answer1Button.setEnabled(true);
		answer2Button.setEnabled(true);
		answer3Button.setEnabled(true);
		answer4Button.setEnabled(true);

		answer1Button.setCompoundDrawablesWithIntrinsicBounds(null, null, null,
				null);
		answer2Button.setCompoundDrawablesWithIntrinsicBounds(null, null, null,
				null);
		answer3Button.setCompoundDrawablesWithIntrinsicBounds(null, null, null,
				null);
		answer4Button.setCompoundDrawablesWithIntrinsicBounds(null, null, null,
				null);
	}

	private void loadState() {
		Question q = getQuestion();
		if (q == null) {
			return;
		}
		SharedPreferences prefs = getPlayPreferences();

		if (prefs.getBoolean(Utils.AUDIENCE_SELECTED_PREFERENCE, false)) {
			int audienceValue = Integer.parseInt(q.getAudience());
			updateButtonFromAudience(audienceValue,
					prefs.getBoolean(Utils.PHONE_SELECTED_PREFERENCE, false));
		}

		if (prefs.getBoolean(Utils.PHONE_SELECTED_PREFERENCE, false)) {
			int phoneValue = Integer.parseInt(q.getPhone());
			updateButtonFromPhone(phoneValue,
					prefs.getBoolean(Utils.AUDIENCE_SELECTED_PREFERENCE, false));
		}

		if (prefs.getBoolean(Utils.FIFTY_SELECTED_PREFERENCE, false)) {
			int fifty1Value = Integer.parseInt(q.getFifty1());
			int fifty2Value = Integer.parseInt(q.getFifty2());
			updateButtonFromFifty(fifty1Value);
			updateButtonFromFifty(fifty2Value);
		}
	}

	private Question getQuestion() {
		if (getCounter() < questions.size()) {
			return questions.get(getCounter());
		}
		return null;
	}

	private void selectedAnswer(String selection) {
		Question q = getQuestion();
		if (q == null) {
			return;
		}

		if (selection.equals(q.getRight())) {
			// Answer right...
			if (getCounter() == questions.size() - 1) {
				// Store quantity
				storeQuantityPreferences();
				// Store scores in local database and remote server
				storeLocalAndRemoteScores();
				// Reset all preferences
				resetAllSharedPreferences();
				// Last answer, win match
				WinnerDialog.getInstance().show(getSupportFragmentManager(),
						"Winner");
			} else {
				// Reset 'selected' preferences
				resetSelectedFromSharedPreferences();
				// Store quantity because match could finish
				storeQuantityPreferences();
				// Show next question
				NextQuestionDialog.getInstance().show(
						getSupportFragmentManager(), "NextQuestion");
			}
		} else {
			// Reset all preferences
			resetAllSharedPreferences();
			// Wrong answer, lost match
			LooserDialog.getInstance().show(getSupportFragmentManager(),
					"Looser");
		}
	}

	public void button1Action(View view) {
		selectedAnswer("1");
	}

	public void button2Action(View view) {
		selectedAnswer("2");
	}

	public void button3Action(View view) {
		selectedAnswer("3");
	}

	public void button4Action(View view) {
		selectedAnswer("4");
	}

	public void storeLocalAndRemoteScores() {
		SharedPreferences prefs = getPlayPreferences();
		int score = prefs.getInt(Utils.QUANTITY_PREFERENCE, 0);

		new LocalScoreRunnable(this).sendScore(score);
		new RemoteScoreRunnable(this).sendScore(score);
	}

	private SharedPreferences sharedPreferences = null;

	private SharedPreferences getPlayPreferences() {
		if (sharedPreferences == null) {
			sharedPreferences = getSharedPreferences(Utils.PLAY_PREFERENCES,
					MODE_PRIVATE);
		}
		return sharedPreferences;
	}

	public void storeQuantityPreferences() {
		Question q = getQuestion();
		if (q == null) {
			return;
		}

		int quantity = 0;

		try {
			int qNumber = Integer.parseInt(q.getNumber());
			if (qNumber < quantities.length) {
				quantity = Integer.parseInt(quantities[qNumber]);
			}
		} catch (NumberFormatException nfe) {
			// this code shouldn't be reached
		}

		SharedPreferences prefs = getPlayPreferences();
		Editor editor = prefs.edit();

		editor.putInt(Utils.QUANTITY_PREFERENCE, quantity);
		editor.commit();
	}

	public void storeQuestionPreferences() {
		SharedPreferences prefs = getPlayPreferences();
		Editor editor = prefs.edit();

		editor.putInt(Utils.QUESTION_PREFERENCE, getCounter());

		editor.commit();
	}

	public void resetSelectedFromSharedPreferences() {
		SharedPreferences prefs = getPlayPreferences();
		Editor editor = prefs.edit();

		editor.putBoolean(Utils.AUDIENCE_SELECTED_PREFERENCE, false);
		editor.putBoolean(Utils.FIFTY_SELECTED_PREFERENCE, false);
		editor.putBoolean(Utils.PHONE_SELECTED_PREFERENCE, false);

		editor.commit();
	}

	public void resetAllSharedPreferences() {
		// reset counter
		updateCounter(0);

		SharedPreferences prefs = getPlayPreferences();
		Editor editor = prefs.edit();

		editor.clear();
		editor.commit();
	}

}
